//	Ordinaire.Database.IDatabase
//	Copyright (c) 2008 Jonathan Loe
//
//	MIT license (http://en.wikipedia.org/wiki/MIT_License)
//
//	Permission is hereby granted, free of charge, to any person obtaining a copy
//	of this software and associated documentation files (the "Software"), to deal
//	in the Software without restriction, including without limitation the rights 
//	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
//	of the Software, and to permit persons to whom the Software is furnished to do so, 
//	subject to the following conditions:
//
//	The above copyright notice and this permission notice shall be included in all 
//	copies or substantial portions of the Software.
//
//	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 
//	INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
//	PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE 
//	FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
//	ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Text;

namespace Ordinaire.Database
{
	public delegate object TransformRowToObject(Dictionary<string, object> row);

	/// <summary>
	/// IDbProvides defines a set of must-have functions of a DatabaseFactory.
	/// </summary>
	/// <seealso cref="Ordinaire.Database.SqlDatabase"/>
	/// <seealso cref="Ordinaire.Database.OleDatabase"/>
	public interface IDatabase
	{
		#region Property methods
		/// <summary>
		/// Returns the connection string of the IDatabase class.
		/// </summary>
		string ConnectionString { get; }
		#endregion

		#region Update methods
		/// <summary>
		/// Updates object properties into a table name of the object type name
		/// with condition field names.
		/// </summary>
		/// <param name="value">object value</param>
		/// <param name="conditionFields">field names as required condition text</param>
		/// <returns>no of affected rows</returns>
		int Update(object value, string[] conditionFields);

		/// <summary>
		/// Updates object properties into a table name of the object type name
		/// with condition field names and field names to exclude.
		/// </summary>
		/// <param name="value">object value</param>
		/// <param name="conditionFields">field names as required condition text</param>
		/// <param name="excludeFields">field names to exclude</param>
		/// <returns>no of affected rows</returns>
		int Update(object value, string[] conditionFields, string[] excludeFields);

		/// <summary>
		/// Updates object properties into a table name of the object type name
		/// with condition field names and field names to exclude and table name prefix.
		/// </summary>
		/// <param name="value">object value</param>
		/// <param name="conditionFields">field names as required condition text</param>
		/// <param name="excludeFields">field names to exclude</param>
		/// <param name="tableName">table name</param>
		/// <returns>no of affected rows</returns>
		int Update(object value, string[] conditionFields, string[] excludeFields, string tableName);
		#endregion

		#region Insert methods
		/// <summary>
		/// Inserts object properties into a table name of the object type name.
		/// </summary>
		/// <param name="value">object</param>
		/// <returns>no of affected rows</returns>
		int Insert(object value);

		/// <summary>
		/// Inserts object properties into a table name of the object type name
		/// with field names to exclude.
		/// </summary>
		/// <param name="value">object</param>
		/// <param name="excludeFields">fields to exclude</param>
		/// <returns>no of affected rows</returns>
		int Insert(object value, string[] excludeFields);

		/// <summary>
		/// Inserts object properties into a table name of the object type name
		/// with field names to exclude and table name prefix.
		/// </summary>
		/// <param name="value">object</param>
		/// <param name="excludeFields">fields to exclude</param>
		/// <param name="tableName">table name</param>
		/// <returns>no of affected rows</returns>
		int Insert(object value, string[] excludeFields, string tableName);
		#endregion

		#region Delete methods
		/// <summary>
		/// Deletes row(s) that matches from the table of a name of the value class name
		/// with the specified conditions.
		/// </summary>
		/// <param name="value">object value</param>
		/// <param name="conditionFields">condition fields to match</param>
		/// <returns>no of affected rows</returns>
		int Delete(object value, string[] conditionFields);

		/// <summary>
		/// Deletes row(s) that matches from the table of a name of the value class name
		/// with the specified conditions and a table name prefix.
		/// </summary>
		/// <param name="value">object value</param>
		/// <param name="conditionFields">condition fields to match</param>
		/// <param name="tableName">table name</param>
		/// <returns>no of affected rows</returns>
		int Delete(object value, string[] conditionFields, string tableName);
		#endregion

		#region Transaction related...
		/// <summary>
		/// Starts a transaction.
		/// </summary>
		/// <returns>true if successful</returns>
		bool StartTransaction();

		/// <summary>
		/// Commits transaction.
		/// </summary>
		void Commit();

		/// <summary>
		/// Rollbacks transaction.
		/// </summary>
		void Rollback();
		#endregion

		#region ExecuteQuery
		#region results as DataTable
		/// <summary>
		/// Executes specified command text and returns result as DataTable class.
		/// </summary>
		/// <param name="commandText">command text</param>
		/// <returns>result set in DataTable class</returns>
		DataTable ExecuteQuery(string commandText);

		/// <summary>
		/// Executes specified command text and command type. Returns result as DataTable class.
		/// </summary>
		/// <param name="commandText">command text</param>
		/// <param name="commandType">command type</param>
		/// <returns>result set in DataTable class</returns>
		DataTable ExecuteQuery(string commandText, CommandType commandType);

		/// <summary>
		/// Executes specified command text with specified parameters. Returns result as DataTable class.
		/// </summary>
		/// <param name="commandText">command text</param>
		/// <param name="parameters">parameters</param>
		/// <returns>result set in DataTable class</returns>
		/// <remarks>Stored procedure is the default command type.</remarks>
		DataTable ExecuteQuery(string commandText, Dictionary<string, object> parameters);

		/// <summary>
		/// Executes specified command text with specified parameters and command type. Returns result as DataTable class.
		/// </summary>
		/// <param name="commandText">command text</param>
		/// <param name="parameters">parameters</param>
		/// <param name="commandType">command type</param>
		/// <returns>result set in DataTable class</returns>
		DataTable ExecuteQuery(string commandText, Dictionary<string, object> parameters, CommandType commandType);
		#endregion

		#region results into List<objects>
		/// <summary>
		/// Executes specified command text and returns result as a list of objects.
		/// </summary>
		/// <param name="transformer">delegate function to transform a row to a desired object</param>
		/// <param name="commandText">command text</param>
		/// <returns>result set in a list of objects</returns>
		List<object> ExecuteQuery(TransformRowToObject transformer, string commandText);

		/// <summary>
		/// Executes specified command text and command type. Returns result as a list of objects.
		/// </summary>
		/// <param name="transformer">delegate function to transform a row to a desired object</param>
		/// <param name="commandText">command text</param>
		/// <param name="commandType">command type</param>
		/// <returns>result set in a list of objects</returns>
		List<object> ExecuteQuery(TransformRowToObject transformer, string commandText, CommandType commandType);

		/// <summary>
		/// Executes specified command text with the specified parameters. Returns result as a list of objects.
		/// </summary>
		/// <param name="commandText">command text</param>
		/// <param name="transformer">delegate function to transform a row to a desired object</param>
		/// <param name="parameters">Db parameters</param>
		/// <returns>result set in a list of objects</returns>
		/// <remarks>Stored procedure is the default command type.</remarks>
		List<object> ExecuteQuery(TransformRowToObject transformer, string commandText, Dictionary<string, object> parameters);

		/// <summary>
		/// Executes specified command text with the specified parameters and command type. Returns result as a list of objects.
		/// </summary>
		/// <param name="commandText">command text</param>
		/// <param name="transformer">delegate function to transform a row to a desired object</param>
		/// <param name="parameters">Db parameters</param>
		/// <param name="commandType">command type</param>
		/// <returns>result set in a list of objects</returns>
		List<object> ExecuteQuery(TransformRowToObject transformer, string commandText, Dictionary<string, object> parameters, CommandType commandType);
		#endregion
		#endregion

		#region ExecuteScalar
		/// <summary>
		/// Executes specified command text and returns the first column of the first row in the result set.
		/// </summary>
		/// <param name="commandText">command text</param>
		/// <returns>object of the first column in first row</returns>
		object ExecuteScalar(string commandText);

		/// <summary>
		/// Executes specified command text and command type.
		/// Returns the first column of the first row in the result set.
		/// </summary>
		/// <param name="commandText">command text</param>
		/// <param name="commandType">command type</param>
		/// <returns>object of the first column in first row</returns>
		object ExecuteScalar(string commandText, CommandType commandType);

		/// <summary>
		/// Executes specified command text with the specified parameters.
		/// Returns the first column of the first row in the result set.
		/// </summary>
		/// <param name="commandText">command text</param>
		/// <param name="parameters">list of parameters</param>
		/// <returns>object of the first column in first row</returns>
		/// <remarks>Stored procedure is the default command type.</remarks>
		object ExecuteScalar(string commandText, Dictionary<string, object> parameters);

		/// <summary>
		/// Executes specified command text with the specified parameters and command type.
		/// Returns the first column of the first row in the result set.
		/// </summary>
		/// <param name="commandText">command text</param>
		/// <param name="parameters">list of parameters</param>
		/// <param name="commandType">command type</param>
		/// <returns>object of the first column in first row</returns>
		object ExecuteScalar(string commandText, Dictionary<string, object> parameters, CommandType commandType);
		#endregion

		#region ExecuteNonQuery
		/// <summary>
		/// Executes a Transact-SQL statement and returns the number of rows affected.
		/// </summary>
		/// <param name="commandText">command text</param>
		/// <returns>number of affected rows</returns>
		int ExecuteNonQuery(string commandText);

		/// <summary>
		/// Executes a SQL command of a specified command type.
		/// Returns the number of rows affected.
		/// </summary>
		/// <param name="commandText">command text</param>
		/// <param name="commandType">command type</param>
		/// <returns>number of affected rows</returns>
		int ExecuteNonQuery(string commandText, CommandType commandType);

		/// <summary>
		/// Executes a SQL command with specified parameters.
		/// Returns the number of rows affected.
		/// </summary>
		/// <param name="commandText">command text</param>
		/// <param name="parameters">list of parameters</param>
		/// <returns>number of affected rows</returns>
		/// <remarks>Stored procedure is the default command type.</remarks>
		int ExecuteNonQuery(string commandText, Dictionary<string, object> parameters);

		/// <summary>
		/// Executes a SQL command with specified parameters and command type.
		/// Returns the number of rows affected.
		/// </summary>
		/// <param name="commandText">command text</param>
		/// <param name="parameters">list of parameters</param>
		/// <param name="commandType">command type</param>
		/// <returns>number of affected rows</returns>
		int ExecuteNonQuery(string commandText, Dictionary<string, object> parameters, CommandType commandType);
		#endregion
	}
}
